package solver

import (
	"log"
	"math/rand"
	"time"
)

func (g *Grid) MakeSolvedGrid() (ok bool) {
	w := log.Writer()
	log.SetOutput(Discard{})
	defer log.SetOutput(w)

	g.Input("")
	g.Init()
	g.Clearup()
	g.Backtrack()
	ok = g.Validate()
	return
}

/*
func (g *Grid) removeCells() {
	w := log.Writer()
	log.SetOutput(Discard{})
	defer log.SetOutput(w)

	cellxys := make([][2]int, 0, 81)
	for i := 0; i < 9; i++ {
		for j := 0; j < 9; j++ {
			cellxys = append(cellxys, [2]int{i, j})
		}
	}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	r.Shuffle(len(cellxys), func(i, j int) {
		cellxys[i], cellxys[j] = cellxys[j], cellxys[i]
	})
	for _, xy := range cellxys {
		temp := Grid(*g)
		g.cells[xy[0]][xy[1]].setValue(0)
		g.solvedCount--

		trial := Grid(*g)
		trial.Init()
		trial.Clearup()
		trial.prepareStrategies()
		//fmt.Println(len(trial.strategies), trial.strategyNames)
		trial.Solve()
		if !trial.Validate() {
			*g = temp
		}
	}
}

*/

func (g *Grid) removeCells() {
	w := log.Writer()
	log.SetOutput(Discard{})
	defer log.SetOutput(w)

	cellxys := make([][2]int, 0, 81)
	for i := 0; i < 9; i++ {
		for j := 0; j < 9; j++ {
			cellxys = append(cellxys, [2]int{i, j})
		}
	}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	r.Shuffle(len(cellxys), func(i, j int) {
		cellxys[i], cellxys[j] = cellxys[j], cellxys[i]
	})
	for _, xy := range cellxys {
		before := Grid(*g)
		g.cells[xy[0]][xy[1]].setValue(0)
		g.solvedCount--

		after := Grid(*g)
		//trial.Init()
		//trial.Clearup()
		//trial.prepareStrategies()
		//fmt.Println(len(trial.strategies), trial.strategyNames)
		g.Init()
		g.Clearup()
		g.Solve()
		if !g.Validate() {
			*g = before
		} else {
			*g = after
		}

	}
}

func (g *Grid) GenerateGrid() string {
	if !g.MakeSolvedGrid() {
		return ""
	}
	g.removeCells()

	return g.String()

}
